#include <QtGui>
#include <QMessageBox>
#include <stdlib.h> // use getevn() to determine rootness

#include "eeeqt.h"

eeeMain::eeeMain(QWidget *parent) : QDialog(parent)
{
   createMainWidgets();
   createSystemTray();
   createConnections();
   setStartupValues();
   fanPrev = fanSpin->value() - 1;
}

void eeeMain::createMainWidgets()
{
   // Main label on top
   mainLayout = new QVBoxLayout();
   
   mainLabel = new QLabel(tr("Please refer to the README before adjusting any settings"));
   mainLayout->addWidget(mainLabel);
   
   // Start Lcd monitors horizontal layout
   lcdLayout = new QHBoxLayout();
   
   rpmLabel = new QLabel(tr("Rpm"));
   lcdLayout->addWidget(rpmLabel);
   rpmLcd = new QLCDNumber();
   rpmLcd->setNumDigits(5);
   rpmLcd->display("0000");
   lcdLayout->addWidget(rpmLcd);
   
   lcdSpacerLeft = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
   lcdLayout->addItem(lcdSpacerLeft);
   
   tempLabel = new QLabel(tr("Temp"));
   lcdLayout->addWidget(tempLabel);
   tempLcd = new QLCDNumber();
   tempLcd->setNumDigits(3);
   tempLcd->display("00");
   lcdLayout->addWidget(tempLcd);
   
   lcdSpacerRight = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
   lcdLayout->addItem(lcdSpacerRight);
   
   mhzLabel = new QLabel(tr("Mhz"));
   lcdLayout->addWidget(mhzLabel);
   mhzLcd = new QLCDNumber();
   mhzLcd->setNumDigits(4);
   mhzLcd->display("000");
   lcdLayout->addWidget(mhzLcd);
   
   mainLayout->addLayout(lcdLayout);
   // Add Line below lcds/above rest of layouts
   lineTop = new QFrame();
   lineTop->setFrameShape(QFrame::HLine);
   lineTop->setFrameShadow(QFrame::Sunken);
   mainLayout->addWidget(lineTop);
   
   // Make one big horizontal layout to hold the bottom half layouts
   bottomLayout = new QHBoxLayout();
   
   // Group box/layout for the spinners
   settingsGroupBox = new QGroupBox(tr("Settings"));
   settingsLayout = new QVBoxLayout();
   
   // Fsb settings...
   fsbLayout = new QHBoxLayout();
   fsbLabel = new QLabel(tr("Fsb"));
   fsbLayout->addWidget(fsbLabel);
   
   fsbSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
   fsbLayout->addItem(fsbSpacer);
   
   fsbSpin = new QSpinBox();
   fsbSpin->setEnabled(true);
   fsbSpin->setMaximum(100);
   fsbSpin->setMinimum(70);
   fsbSpin->setValue(70);
   fsbLayout->addWidget(fsbSpin);
   settingsLayout->addLayout(fsbLayout);
   
   // Fan Speed settings
   fanLayout = new QHBoxLayout();
   fanLabel = new QLabel(tr("Fan Speed"));
   fanLayout->addWidget(fanLabel);
   
   fanSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
   fanLayout->addItem(fanSpacer);
   
   fanSpin = new QSpinBox();
   fanSpin->setEnabled(false);
   fanSpin->setMaximum(100);
   fanSpin->setValue(40);
   fanLayout->addWidget(fanSpin);
   settingsLayout->addLayout(fanLayout);
   
   // Warnings Settings
   warnLayout = new QHBoxLayout();
   warnLabel = new QLabel(tr("Warning"));
   warnLayout->addWidget(warnLabel);
   
   warnSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
   warnLayout->addItem(warnSpacer);
   
   warnSpin = new QSpinBox();
   warnSpin->setEnabled(false);
   warnSpin->setMaximum(100);
   warnSpin->setValue(60);
   warnLayout->addWidget(warnSpin);
   settingsLayout->addLayout(warnLayout);
   
   settingsDefault = new QPushButton(tr("Restore Defaults"));
   settingsLayout->addWidget(settingsDefault);
   
   // Add the settings layout to the groupbox to the bottomlayout
   settingsGroupBox->setLayout(settingsLayout);
   bottomLayout->addWidget(settingsGroupBox);
   
   // End settings container
   // Start right layout
   rightLayout = new QVBoxLayout();
   
   fanCheck = new QCheckBox(tr("Manual Fan Control"));
   rightLayout->addWidget(fanCheck);
   
   warnCheck = new QCheckBox(tr("Temperature Warning"));
   rightLayout->addWidget(warnCheck);
   
   trayCheck = new QCheckBox(tr("Stay in System Tray"));
   rightLayout->addWidget(trayCheck);
   
   rightLine = new QFrame();
   rightLine->setFrameShape(QFrame::HLine);
   rightLine->setFrameShadow(QFrame::Sunken);
   rightLayout->addWidget(rightLine);
   
   applyButton = new QPushButton(tr("Apply Settings"));
   rightLayout->addWidget(applyButton);
   
   closeButton = new QPushButton(tr("Close"));
   rightLayout->addWidget(closeButton);
   
   rightSpacer = new QSpacerItem(20, 40, QSizePolicy::Expanding, QSizePolicy::Minimum);
   rightLayout->addItem(rightSpacer);
   
   bottomLayout->addLayout(rightLayout);
   mainLayout->addLayout(bottomLayout);
   
   statusBar = new QStatusBar;
   statusBar->setSizeGripEnabled(false);
   // Monkey buisness... Changes startup status depending on isRoot()
   isRoot() ? statusBar->showMessage(tr("Rootness is in you..."),10000) : statusBar->showMessage(tr("Lack of root, you cannot adjust hardware"),10000);
   mainLayout->addWidget(statusBar);
   
   setLayout(mainLayout);
   //End Laying out of widgets
   
   setWindowTitle(tr("eeepc QTweak"));
   
   //Start timer, its a widget, eh? Called every 5 seconds to update the lcd's
   timer = new QTimer(this);
   connect(timer, SIGNAL(timeout()), this, SLOT(updateLcd()));
   timer->start(5000);
}

void eeeMain::createSystemTray()
{
   //Actions for the systray context menu
   restoreAction = new QAction(tr("&Restore"), this);
   connect(restoreAction, SIGNAL(triggered()), this, SLOT(eeeRestore()));
   aboutAction = new QAction(tr("&About"), this);
   connect(aboutAction, SIGNAL(triggered()), this, SLOT(aboutShow()));
   quitAction = new QAction(tr("&Quit"), this);
   connect(quitAction, SIGNAL(triggered()), this, SLOT(close()));
 
   // Actual context menu
   trayIconMenu = new QMenu(this);
   trayIconMenu->addAction(restoreAction);
   trayIconMenu->addAction(aboutAction);
   trayIconMenu->addSeparator();
   trayIconMenu->addAction(quitAction);
   
   // The icon itesl
   trayIcon = new QSystemTrayIcon(this);
   trayIcon->setIcon(QIcon(":/images/icon.svg"));
   trayIcon->setContextMenu(trayIconMenu);
   //*** maybe make it not shown by default?
   trayIcon->show();
   setWindowIcon(QIcon(":/images/icon.svg"));
}

void eeeMain::createConnections()
{
   connect(fanCheck, SIGNAL(toggled(bool)), this, SLOT(fanControlToggle(bool)));
   connect(warnCheck, SIGNAL(toggled(bool)), this, SLOT(tempWarningToggle(bool)));
   connect(trayCheck, SIGNAL(toggled(bool)), this, SLOT(sysTrayToggle(bool)));
   connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
   connect(settingsDefault, SIGNAL(clicked()), this, SLOT(setDefaults()));
   connect(applyButton, SIGNAL(clicked()), this, SLOT(applySettings()));
   connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
}


// Implement the gui logic first, after that will be the
// stuff to actually overclock etc etc

void eeeMain::fanControlToggle(bool checked)
{
   fanSpin->setEnabled(checked ? true: false);
   
   if(!checked)
     {
	myIface.setFanManual(0);
	statusBar->showMessage(tr("Manual fan control off"),5000);
     }
}

void eeeMain::tempWarningToggle(bool checked)
{
   warnSpin->setEnabled(checked ? true: false);
}

void eeeMain::sysTrayToggle(bool checked)
{
   checked ? sysTrayOn = 1: sysTrayOn = 0;
}


void eeeMain::closeEvent(QCloseEvent *event)
{
   if(sysTrayOn == 1)
     {
	this->hide();
	event->ignore();
	sysTrayOn = 0;
     }
   else
     event->accept();
}

void eeeMain::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
   if(reason == QSystemTrayIcon::Trigger)
     eeeRestore();
}

void eeeMain::eeeRestore()
{
   sysTrayOn = 1;
   this->show();
}

void eeeMain::aboutShow()
{
   statusBar->showMessage("Written by John Youngquist (jagonjohn@gmail.com)",10000);
   QMessageBox::information(this, tr("About!!!"), tr("Written by John Youngquist<br><br>Licensed under the GPLv2<br><br>Email jagonjohn@gmail.com for answers"), QMessageBox::Ok);
}

void eeeMain::updateLcd()
{
   int temp = myIface.getTemp();
   tempLcd->display(temp);
   
   int rpm = myIface.getFanRpm();
   rpmLcd->display(rpm);
      
   QString toolText = tr("Temp: %1C - Rpm: %2").arg(temp).arg(rpm);
      
   trayIcon->setToolTip(toolText);
   if(warningOn == 1)
     if(temp >= warningTemp)
       baloonWarningShow(temp);
}

void eeeMain::setDefaults()
{
   fsbSpin->setValue(defFsb);
   fanSpin->setValue(defFan);
}


void eeeMain::setStartupValues()
{
   int defFsb = myIface.getFsb();
   curFsb = defFsb;
   fsbSpin->setValue(defFsb);
   mhzLcd->display(defFsb * 9);   
   
   int defFan = myIface.getFanSpeed();
   fanPrev = defFan;
   fanSpin->setValue(defFan);
}

void eeeMain::applySettings()
{
   QString statusMsg;
   if(fanCheck->isChecked())
     {
	if(fanPrev != fanSpin->value())
	   {
	      if(isRoot())
		{		   
		   myIface.setFanManual(1);
	           myIface.setFanSpeed(fanSpin->value());
		   
		   statusMsg = tr("Fan changed to %1").arg(fanSpin->value());
		   fanPrev = fanSpin->value();
		}
	      else statusMsg = tr("Not root!");
	   }
     }
   
   if(curFsb == fsbSpin->value())
     {
	//do NOTHING
     }
   
   else
     {
	if(isRoot())
	   {	
	      int a = fsbSpin->value() - 70;
	      int b = a/2;
	      int first = 70 + b;
	   
	      myIface.setFsb(first);
	      myIface.setFsb(fsbSpin->value());

	      if(statusMsg.size() == 0)
		statusMsg = tr("Fsb set to %1").arg(fsbSpin->value());  
	      else 
		statusMsg = tr("%1, Fsb set to %2").arg(statusMsg).arg(fsbSpin->value());
	      
	      curFsb = fsbSpin->value();
	      mhzLcd->display(curFsb * 9);
	   }
     }
   statusBar->showMessage(statusMsg,10000);
   statusMsg = "";
   
   if(warnCheck->isChecked())
     {
	warningTemp = warnSpin->value();
	warningOn = 1;
     }
   else 
	warningOn = 0;
}

void eeeMain::baloonWarningShow(int temp)
{
   QString tit = "Overheating...";
   QString msg = tr("The temperature is %1C and you have set your waring to %2C, please adjust your settings").arg(temp).arg(warningTemp);
   trayIcon->showMessage(tit, msg, QSystemTrayIcon::MessageIcon(3), 10000);
   statusBar->showMessage("Warning temperature has been exceeded!!");
}

bool eeeMain::isRoot()
{
   QString user = getenv("USER");
   return (user == "root" ? true : false);
}
